package com.sky.utils;

import com.obs.services.ObsClient;
import com.obs.services.model.PutObjectRequest;
import com.obs.services.model.TemporarySignatureRequest;
import com.obs.services.model.TemporarySignatureResponse;
import com.sky.config.OBSConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class HwOssUtil  {

    @Autowired
    private ObsClient obsClient;

    @Autowired
    private OBSConfig obsConfig;


    public String uploadFile(MultipartFile file) throws IOException {
        return uploadFile(file, "review/file");
    }


    public String uploadFile(MultipartFile file, String fileDir) throws IOException {
        return uploadFileWithName(file, fileDir, null);
    }


    public String uploadFileWithName(MultipartFile file, String fileDir, String fileName) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("上传文件不能为空");
        }

        // 检查OBS客户端是否可用
        try {
            obsClient.headBucket(obsConfig.getBucketName());
            log.info("OBS连接测试成功");
        } catch (Exception e) {
            log.error("OBS连接测试失败", e);
            throw new RuntimeException("OBS服务不可用: " + e.getMessage());
        }

        // 处理文件名
        String originalFilename = file.getOriginalFilename();
        String suffix = StringUtils.getFilenameExtension(originalFilename);
        String newFileName;
        
        if (fileName != null && !fileName.isEmpty()) {
            // 使用自定义文件名，确保包含扩展名
            newFileName = fileName.contains(".") ? fileName : fileName + "." + suffix;
        } else {
            // 生成随机文件名
            newFileName = generateFileName(suffix);
        }

        // 构建文件路径
        String objectKey = buildObjectKey(fileDir, newFileName);
        
        log.info("开始上传文件到OBS, bucket: {}, objectKey: {}, 文件大小: {} bytes", 
            obsConfig.getBucketName(), objectKey, file.getSize());

        try {
            // 创建上传请求
            PutObjectRequest request = new PutObjectRequest();
            request.setBucketName(obsConfig.getBucketName());
            request.setObjectKey(objectKey);
            request.setInput(file.getInputStream());

            // 上传文件
            obsClient.putObject(request);
            log.info("文件上传到OBS成功: {}", objectKey);

            // 返回文件访问URL
            String endpoint = obsConfig.getEndPoint();
            if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
                endpoint = endpoint.substring(endpoint.indexOf("://") + 3);
            }
            String fileUrl = String.format("https://%s.%s/%s",
                obsConfig.getBucketName(),
                endpoint,
                objectKey);
                
            log.info("生成文件访问URL: {}", fileUrl);
            return fileUrl;
        } catch (Exception e) {
            log.error("文件上传失败, bucket: {}, objectKey: {}, 错误: {}", 
                obsConfig.getBucketName(), objectKey, e.getMessage(), e);
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }


    public boolean deleteFile(String fileUrl) {
        if (!StringUtils.hasText(fileUrl)) {
            return false;
        }

        try {
            // 从URL中提取对象键
            String objectKey = extractObjectKey(fileUrl);
            if (objectKey == null) {
                return false;
            }

            // 删除文件
            obsClient.deleteObject(obsConfig.getBucketName(), objectKey);
            return true;
        } catch (Exception e) {
            log.error("文件删除失败", e);
            return false;
        }
    }

    /**
     * 生成唯一的文件名
     */
    private String generateFileName(String suffix) {
        // 使用时间戳和UUID生成唯一文件名
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        return String.format("%s_%s.%s", timestamp, uuid, suffix);
    }

    /**
     * 构建对象键（文件在OBS中的完整路径）
     */
    private String buildObjectKey(String fileDir, String fileName) {
        if (StringUtils.hasText(fileDir)) {
            // 确保目录以/结尾
            if (!fileDir.endsWith("/")) {
                fileDir += "/";
            }
            // 确保目录不以/开头
            if (fileDir.startsWith("/")) {
                fileDir = fileDir.substring(1);
            }
            return fileDir + fileName;
        }
        return fileName;
    }

    /**
     * 从文件URL中提取对象键
     */
    private String extractObjectKey(String fileUrl) {
        String endpoint = obsConfig.getEndPoint();
        if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
            endpoint = endpoint.substring(endpoint.indexOf("://") + 3);
        }
        String bucketEndpoint = obsConfig.getBucketName() + "." + endpoint;
        int index = fileUrl.indexOf(bucketEndpoint);
        if (index != -1) {
            return fileUrl.substring(index + bucketEndpoint.length() + 1);
        }
        return null;
    }
    

    public String generatePresignedUrl(String fileUrl, long expireTime) {
        // 调用新方法，默认使用inline=true保持原有行为
        return generatePresignedUrl(fileUrl, expireTime, true);
    }
    

    public String generatePresignedUrl(String fileUrl, long expireTime, boolean inline) {
        if (!StringUtils.hasText(fileUrl)) {
            throw new IllegalArgumentException("文件URL不能为空");
        }

        try {
            // 从URL中提取对象键
            String objectKey = extractObjectKey(fileUrl);
            if (objectKey == null) {
                // 如果无法从URL中提取对象键，则假设传入的是对象键
                objectKey = fileUrl;
            }

            // 创建临时签名请求
            TemporarySignatureRequest request = new TemporarySignatureRequest();
            request.setBucketName(obsConfig.getBucketName());
            request.setObjectKey(objectKey);
            request.setExpires(expireTime);
            
            // 可以添加额外的查询参数
            Map<String, Object> queryParams = new HashMap<>();
            // 根据inline参数设置不同的content-disposition
            String disposition = inline ? "inline" : "attachment";
            queryParams.put("response-content-disposition", disposition);
            request.setQueryParams(queryParams);

            // 生成临时签名URL
            TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
            
            log.info("生成预签名URL成功: {}, disposition: {}", response.getSignedUrl(), disposition);
            return response.getSignedUrl();
        } catch (Exception e) {
            log.error("生成预签名URL失败", e);
            throw new RuntimeException("生成预签名URL失败: " + e.getMessage());
        }
    }
}
